package network;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/**
 * date: 2023-2-28
 * UCP：无连接、不可靠传输、面向数据报、全双工（一个 socket 既可以发，也可以收）
 * UDP 版本的回显客户端
 */
public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIP = null;
    private int serverPort = 0;

    public UdpEchoClient(String serverIP,int serverPort) throws SocketException {
        socket = new DatagramSocket(); // 构造这个 socket 对象，不需要显示绑定一个端口（让操作系统自动分配一个端口）
        /*
        服务器的 端口 是要固定指定的，目的是为了方便客户端找到服务器程序
        客户端的 端口 是由系统自动分配的。如果手动指定，可能和客户端其他程序的端口冲突
        为啥 服务器 不怕冲突，因为服务器上面的程序可控，客户端是运行在电脑上的，环境更复杂，更不可控。
        一次通信，需要有两个 IP，两个端口
        客户端的IP是127.0.0.1 已知。客户端的port是系统自动分配的
        服务器的IP和port也需要告诉客户端，才能顺利吧消息发给服务器
         */
        socket = new DatagramSocket();
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }

    public void start() throws IOException {
        System.out.println("客户端启动！");
        Scanner scanner = new Scanner(System.in);
        while (true) {
            // 1. 从控制台读取要发送的数据
            System.out.print("> ");
            String request = scanner.next();
            if(request.equals("exit")) {
                System.out.println("goodbye");
                break;
            }

            // 2. 构造 UDP 请求，并发送
            /*
            构造这个 Packet 的时候，需要把 serverIP 和port 都传入进来，但是此时的 IP 地址需要填写的是一个 32位 的整数形式，
            上述的 IP地址 是一个字符串，需要使用 InetAddress.getByName 来进行一个转换
             */
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(serverIP),serverPort);
            socket.send(requestPacket);

            // 3. 读取服务器的 UDP 响应，并解析
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(), 0, requestPacket.getLength());

            // 4. 把解析好的结果显示出来
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        client.start();
    }
}
